import asyncio
import inspect

from dashscope.audio.asr import TranslationRecognizerRealtime, TranslationRecognizerCallback
from dashscope.audio.asr import TranscriptionResult, TranslationResult
from json import dumps

from src.server import getNeedTranslationLanguages


# 使用回调函数来处理翻译结果，避免循环导入
class TranslationCallback(TranslationRecognizerCallback):
    def __init__(self, meeting_id, on_translation):
        self.meeting_id = meeting_id
        self.on_translation = on_translation
    
    def on_open(self) -> None:
        print("TranslationRecognizerCallback open.")
    
    def on_close(self) -> None:
        print("TranslationRecognizerCallback close.")
    
    def on_event(self, request_id, transcription_result: TranscriptionResult, translation_result: TranslationResult, usage) -> None:
        
        if transcription_result is not None:
            print('transcription: {}'.format(transcription_result.text))
            if transcription_result.stash is not None:
                print('transcription stash: {}'.format(transcription_result.stash.text))
            if transcription_result.is_sentence_end:
                print('request id: ', request_id)
                print('usage: ', usage)
        
        if translation_result is not None:
            print(f"translation_languages: {translation_result.get_language_list()}")
            for lang in translation_result.get_language_list():
                translation = translation_result.get_translation(lang)

                print('translate to {}: {}'.format(lang, translation.text))
                if translation.stash is not None:
                    print('translate to {} stash: {}'.format(lang, translation.stash.text, ))
                if translation.is_sentence_end:
                    print('request id: ', request_id)
                    print('usage: ', usage)
                    print(f"translate to {lang}: {translation.text}")

                    # 调用回调函数处理翻译结果
                    if self.on_translation:
                        try:
                            # 检查回调函数是否为异步函数
                            if inspect.iscoroutinefunction(self.on_translation):
                                # 异步函数，确保在事件循环中运行
                                try:
                                    # 尝试在当前线程的事件循环中运行
                                    loop = asyncio.get_running_loop()
                                    loop.create_task(self.on_translation(self.meeting_id, lang, dumps({
                                        "sentence_id": transcription_result.sentence_id,
                                        "transcription": transcription_result.text,
                                        "translation": translation.text,
                                    })))
                                except RuntimeError:
                                    # 当前线程没有事件循环，创建一个新的事件循环
                                    loop = asyncio.new_event_loop()
                                    asyncio.set_event_loop(loop)
                                    # 使用run_in_executor在后台运行，避免阻塞
                                    from concurrent.futures import ThreadPoolExecutor
                                    executor = ThreadPoolExecutor(max_workers=1)
                                    loop.run_in_executor(executor, lambda: asyncio.run(self.on_translation(
                                        self.meeting_id, lang, dumps({
                                            "sentence_id": transcription_result.sentence_id,
                                            "transcription": transcription_result.text,
                                            "translation": translation.text,
                                        })
                                    )))
                            else:
                                # 同步函数，直接调用
                                self.on_translation(self.meeting_id, lang, dumps({
                                    "sentence_id": transcription_result.sentence_id,
                                    "transcription": transcription_result.text,
                                    "translation": translation.text,
                                }))
                        except Exception as e:
                            print(f"翻译回调函数异常: {e}")
    
    def on_error(self, request_id, error_code, error_message) -> None:
        print(f"on_error: request_id={request_id}, error_code={error_code}, error_message={error_message}")


class TranslationService:
    def __init__(self, meeting_id, langs=[], on_translation=None):
        self.meeting_id = meeting_id
        self.source_langs = langs
        self.translators = {}
        self.on_translation = on_translation
        self.callback = TranslationCallback(meeting_id, on_translation)
    
    def send_audio(self, audio_data):
        # 每次发过来新的音频片段时检测下是否需要多加一个翻译器
        need_languages = getNeedTranslationLanguages(self.meeting_id)  # e.g ["zh", "en"]
        
        # 检查是否有不需要的翻译器
        for lang in self.translators.keys():
            if lang not in need_languages:
                self.translators[lang].stop()
                del self.translators[lang]
        
        # 检查是否需要添加新的翻译器
        for lang in need_languages:
            if lang not in self.translators.keys():
                # 判断是否固定翻译源语言
                if len(self.source_langs) == 2 and lang in self.source_langs:
                    self.translators[lang] = TranslationRecognizerRealtime(
                        model="gummy-realtime-v1",
                        format="pcm",
                        sample_rate=16000,
                        transcription_enabled=True,
                        translation_source_language=self.source_langs[0] if lang == self.source_langs[1] else self.source_langs[1],
                        translation_enabled=True,
                        translation_target_languages=[lang],
                        callback=self.callback,
                    )
                else:
                    self.translators[lang] = TranslationRecognizerRealtime(
                        model="gummy-realtime-v1",
                        format="pcm",
                        sample_rate=16000,
                        transcription_enabled=True,
                        translation_enabled=True,
                        translation_target_languages=[lang],
                        callback=self.callback,
                    )
                self.translators[lang].start()
                print(f"添加翻译器: {lang}")
        
        for lang in self.translators.keys():
            try:
                self.translators[lang].send_audio_frame(audio_data)
            except Exception as e:
                print(f"发送音频数据失败: {e}")
    
    def stop(self):
        for lang in self.translators.keys():
            self.translators[lang].stop()
            print(f"停止翻译器: {lang}")
